<?php
// $Id$

/**
 * Smslog 封装来自 sms_log 数据表的记录及领域逻辑
 */
class coreorder extends QDB_ActiveRecord_Abstract
{

    /**
     * 返回对象的定义
     *
     * @static
     *
     * @return array
     */
    static function __define()
    {
        return array
        (
            // 指定该 ActiveRecord 要使用的行为插件
            'behaviors' => '',

            // 指定行为插件的配置
            'behaviors_settings' => array
            (
                # '插件名' => array('选项' => 设置),
            ),

            // 用什么数据表保存对象
            'table_name' => 'edu_core_order',

            // 指定数据表记录字段与对象属性之间的映射关系
            // 没有在此处指定的属性，QeePHP 会自动设置将属性映射为对象的可读写属性
            'props' => array
            (
                // 主键应该是只读，确保领域对象的“不变量”
                'id' => array('readonly' => true),

                // 对象创建时间应该是只读
                'created' => array('readonly' => true),


                /**
                 *  可以在此添加其他属性的设置
                 */
                # 'other_prop' => array('readonly' => true),

                /**
                 * 添加对象间的关联
                 */
                # 'other' => array('has_one' => 'Class'),
//         	'agent'=>array('has_one'=>'acct','source_key'=>'agent_id','target_id'=>'id'),
//             'admin'=>array('has_one'=>'acct','source_key'=>'admin_id','target_id'=>'id')

            ),

            /**
             * 允许使用 mass-assignment 方式赋值的属性
             *
             * 如果指定了 attr_accessible，则忽略 attr_protected 的设置。
             */
            'attr_accessible' => '',

            /**
             * 拒绝使用 mass-assignment 方式赋值的属性
             */
            'attr_protected' => 'id',

            /**
             * 指定在数据库中创建对象时，哪些属性的值不允许由外部提供
             *
             * 这里指定的属性会在创建记录时被过滤掉，从而让数据库自行填充值。
             */
            'create_reject' => '',

            /**
             * 指定更新数据库中的对象时，哪些属性的值不允许由外部提供
             */
            'update_reject' => '',

            /**
             * 指定在数据库中创建对象时，哪些属性的值由下面指定的内容进行覆盖
             *
             * 如果填充值为 self::AUTOFILL_TIMESTAMP 或 self::AUTOFILL_DATETIME，
             * 则会根据属性的类型来自动填充当前时间（整数或字符串）。
             *
             * 如果填充值为一个数组，则假定为 callback 方法。
             */
            'create_autofill' => array
            (
                # 属性名 => 填充值
                # 'is_locked' => 0,
              'created' => self::AUTOFILL_TIMESTAMP ,
            ),

            /**
             * 指定更新数据库中的对象时，哪些属性的值由下面指定的内容进行覆盖
             *
             * 填充值的指定规则同 create_autofill
             */
            'update_autofill' => array
            (
            ),

            /**
             * 在保存对象时，会按照下面指定的验证规则进行验证。验证失败会抛出异常。
             *
             * 除了在保存时自动验证，还可以通过对象的 ::meta()->validate() 方法对数组数据进行验证。
             *
             * 如果需要添加一个自定义验证，应该写成
             *
             * 'title' => array(
             *        array(array(__CLASS__, 'checkTitle'), '标题不能为空'),
             * )
             *
             * 然后在该类中添加 checkTitle() 方法。函数原型如下：
             *
             * static function checkTitle($title)
             *
             * 该方法返回 true 表示通过验证。
             */
            'validations' => array
            (
                
            ),
        );
    }


/* ------------------ 以下是自动生成的代码，不能修改 ------------------ */

    /**
     * 开启一个查询，查找符合条件的对象或对象集合
     *
     * @static
     *
     * @return QDB_Select
     */
    static function find()
    {
        $args = func_get_args();
        return QDB_ActiveRecord_Meta::instance(__CLASS__)->findByArgs($args);
    }

    /**
     * 返回当前 ActiveRecord 类的元数据对象
     *
     * @static
     *
     * @return QDB_ActiveRecord_Meta
     */
    static function meta()
    {
        return QDB_ActiveRecord_Meta::instance(__CLASS__);
    }


/* ------------------ 以上是自动生成的代码，不能修改 ------------------ */

    //生成订单编号
    static function getorderno()
    {
        $order_no = date('YmdHis').substr ( uniqid (), 6 );
        return $order_no;
       
    }

    //根据订单获取微信支付参数
    static function payorder($order_id,$openid,$acctid){

        $order_info = coreorder::find('id = '.$order_id)->getOne();
        $acctobj=acct::find(array("id"=>$acctid))->setColumns('id,mch_id,key,app_id,app_secret')->getOne();
        if(!$acctobj->id()){
            $result = array('code'=>2,'msg'=>urlencode('用户所属商家不存在'));
            exit(json_encode($result));
        }
        $wxmchid=trim($acctobj->mch_id);
        $wxkey=trim($acctobj->key);
        $wxappid=trim($acctobj->app_id);
        $wxappsecret = trim($acctobj->app_secret);
        if(!$wxmchid || !$wxkey ||!$wxappid || !$wxappsecret){
            $result = array('code'=>3,'msg'=>urlencode('微信配置不完整'));
            exit(json_encode($result));
        }
        $payfees = $order_info->fee;
        $pay_total = sprintf('%.2f', $order_info->fee)*100;
        // 调用支付宝进行支付
        $config = array(
                'APPID'=>$wxappid,
                'MCHID'=>$wxmchid,
                'WXKEY'=> $wxkey,
                'APPSECRET'=>$wxappsecret,
                'ip'=>Helper_Common::get_ip(),
        );
        $data = array(
            'user_id'=>$order_info->user_id,
            'payfee'=>$payfees
            );

        WxPayConfig::setconfig($acctobj);
        $body = '微信在线支付';
        $url = Helper_Common::getRequestHost();
        $notityUrl = $url . "wxnotify/importcallback";
        $trade_type = 'JSAPI';
        //$Device_info='WEB';
        //给需要提交的必须参数赋值
        $wxpay = new WxPayUnifiedOrder();
        //$wxpay->SetDevice_info($Device_info);
        $wxpay->SetBody($body);
        $wxpay->SetOut_trade_no($order_info->ordersn);
        $wxpay->SetTotal_fee($pay_total);
        $wxpay->SetNotify_url($notityUrl);
        $wxpay->SetTrade_type($trade_type);
        $wxpay->SetAttach(json_encode($data));
        $wxpay->SetOpenid($openid);
        $order =  Helper_WxPayApi::unifiedOrder($wxpay, $config);
        if(empty($order['prepay_id'])){
            //$result = array('code'=>2,'msg'=>$order[]);
            if($order['return_code']=='FAIL'){
                echo json_encode(array('code'=>1,'msg'=>$order['return_msg']));
                exit();
            }
            //return $order;
            //exit(json_encode($order));
        }
        $order_info->prepay_id=$order['prepay_id'];
        $order_info->save();
        $arr = array();
        $arr['appId'] = $order["appid"];
        $arr['nonceStr'] = $order["nonce_str"];
        $arr['package'] = "prepay_id=".$order['prepay_id'];
        $arr['signType'] = "MD5";
        $arr['timeStamp'] = (string)time();
        $str = Helper_Common::ToUrlParams($arr);
        $jmstr = $str."&key=".$acctobj->key;
        $arr['paySign'] = strtoupper(MD5($jmstr));
        $arr['notityUrl'] = $notityUrl;
        $arr['notis'] = $data;
        return $arr;
    }

    //支付完成回调
    static function notifyOK($id){
        $coreorder = coreorder::find(array("id"=>$id))->getOne();
        //修改支付状态
        if($coreorder->status==0){
            $coreorder->status=1;
            $coreorder->save();
            
            switch ($coreorder->module_mark) {
                case 'video':
                    videoorder::payok($coreorder->orderid);
                    break;
                case 'shop':
                    shoporder::payok($coreorder->orderid);
                    # code...
                    break;
                case 'reward':
                    videoreward::payok($coreorder->orderid);
                    # code...
                    break;
                case 'vip':
                    viporder::payok($coreorder->orderid);
                    # code...
                    break;
                case 'activity':
                    activityorder::payok($coreorder->orderid);
                    # code...
                    break;
                case 'paper':
                    paperorder::payok($coreorder->orderid);
                    # code...
                    break;
                default:
                    # code...
                    break;
            }
            //分销提成
            fxcommission::addcommission($id);
        }
        
    }
    /**
     * 企业付款
     * @param type $openid openid
     * @param type $paytype 支付类型 1 微信
     * @param type $money
     */
    static function company_pay($openid = '', $money = 0,  $desc = '', $return = true)
    {
        $return = array("status"=>-1,"msg"=>"");

        if (empty($money)) {
            $return['msg'] = '金额不能为空';
            return $return;
        }
        $acct = acct::find("id=?",1)->getOne();

        if (empty($acct->app_id)) {
            $return['msg'] = '未设置小程序 APPID';
            return $return;
        }

        if (empty($acct->mch_id)) {
            $return['msg'] = '未设置小程序微信支付商户号';
            return $return;
        }

        if (empty($acct->key)) {
            $return['msg'] = '未设置小程序微信商户apikey';
            return $return;
        }

        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
        $pars = array();
        $pars['mch_appid'] = $acct->app_id;
        $pars['mchid'] = $acct->mch_id;
        $pars['nonce_str'] = Helper_Common::get_rand_str(32,false);
        $pars['partner_trade_no'] = empty($trade_no) ? date('YmdHis',time()) . substr ( uniqid (), 6 ) : $trade_no;
        $pars['openid'] = $openid;
        $pars['check_name'] = 'NO_CHECK';
        $pars['amount'] = $money;
        $pars['desc'] = empty($desc) ? '现金提现' : $desc;
        $pars['spbill_create_ip'] = "39.105.151.191";//gethostbyname($_SERVER['HTTP_HOST']);

        ksort($pars, SORT_STRING);
        $string1 = '';

        foreach ($pars as $k => $v) {
            $string1 .= $k . '=' . $v . '&';
        }

        $string1 .= 'key=' . $acct->key;
        $pars['sign'] = strtoupper(md5($string1));
        // $xml = array2xml($pars);
        $extras = array();
        $errmsg = '未设置微信支付证书!';

        if (empty($acct->cert_pem) || empty($acct->key_pem)) {
            $return['msg'] = $errmsg;
            return $return;
        }
        global $root_dir;
        if(!is_dir($root_dir . '/cert/')){
            mkdir($root_dir . '/cert/');
        }
        $certfile = $root_dir . '/cert/' . Helper_Common::get_rand_str(32,false);
        file_put_contents($certfile, $acct->cert_pem);
        $keyfile =  $root_dir . '/cert/' . Helper_Common::get_rand_str(32,false);
        file_put_contents($keyfile, $acct->key_pem);
        $extras['certPath'] = $certfile;
        $extras['keyPath'] = $keyfile;


        $arr = Helper_Common::post_data($url,$pars,"xml",true,$extras); //ihttp_request($url, $xml, $extras);
        @unlink($certfile);
        @unlink($keyfile);

        if ($arr['return_code'] == 'SUCCESS' && $arr['result_code'] == 'SUCCESS') {
            $return['status']=0;
            return $return;
        }

        if ($arr['return_code'] == 'SUCCESS' && $arr['result_code'] == 'FAIL' && $arr['return_msg'] == 'OK') {
            if ($arr['err_code'] == 'NOTENOUGH') {
                $return['msg'] = "账号余额不足";
                return $return;

            }else{
                $return['msg'] = $arr['err_code'];
                return $return;
            }
        }
        else {
            if ($arr['return_msg'] == $arr['err_code_des']) {
                $error = $arr['return_msg'];
            }
            else {
                $error = $arr['return_msg'] . ' | ' . $arr['err_code_des'];
            }

            $return['msg'] = $error;
            return $return;
        }
    }

    /**
     * 退款
     * @Author   xy
     * @DateTime 2019-08-30T15:17:05+0800
     * @param    [type]                   $order_id [description]
     * @param    [type]                   $price    [description]
     * @return   [type]                             [description]
     */
    static function refund($order_id,$price){
        $return = array("status"=>-1,"msg"=>"");
        if (empty($order_id)) {
            $return['msg'] = 'order_id不能为空';
            return $return;
        }

        $order = coreorder::find("id=?",$order_id)->getOne();

        if (!$order->id()) {
            $return['msg'] = '未找到订单';
            return $return;
        }
        if (empty($price)) {
            $return['msg'] = '金额不能为空';
            return $return;
        }
        $acct = acct::find("id=?",$order->acct_id)->getOne();

        if (empty($acct->app_id)) {
            $return['msg'] = '未设置小程序 APPID';
            return $return;
        }

        if (empty($acct->mch_id)) {
            $return['msg'] = '未设置小程序微信支付商户号';
            return $return;
        }

        if (empty($acct->key)) {
            $return['msg'] = '未设置小程序微信商户apikey';
            return $return;
        }
        $user = acctuser::find('id=?',$order->user_id)->getOne();
        if(!$user->id()){
            $return['msg'] = '用户不存在';
            return $return;
        }
        $payment = payment::find("core_id=?",$order->id)->getOne();
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
        $pars = array();
        $pars['appid'] = $acct->app_id;
        $pars['mch_id'] = $acct->mch_id;
        $pars['nonce_str'] = Helper_Common::get_rand_str(32,false);
        $pars['out_trade_no'] = $payment->id()?$payment->payment_sn:$order->ordersn;//兼容新增payment
        $pars['out_refund_no'] = "R_".$order->ordersn;
        $pars['total_fee'] = $order->fee*100;
        $pars['refund_fee'] = $price*100;
        $pars['op_user_id'] = $user->wechat_open_id;

        ksort($pars, SORT_STRING);
        $string1 = '';

        foreach ($pars as $k => $v) {
            $string1 .= $k . '=' . $v . '&';
        }

        $string1 .= 'key=' . $acct->key;
        $pars['sign'] = strtoupper(md5($string1));
        // $xml = array2xml($pars);
        $extras = array();
        $errmsg = '未设置微信支付证书!';

        if (empty($acct->cert_pem) || empty($acct->key_pem)) {
            $return['msg'] = $errmsg;
            return $return;
        }

        global $root_dir;
        if(!is_dir($root_dir . '/cert/')){
            mkdir($root_dir . '/cert/');
        }
        $certfile = $root_dir . '/cert/' . Helper_Common::get_rand_str(32,false);
        file_put_contents($certfile, $acct->cert_pem);
        $keyfile =  $root_dir . '/cert/' . Helper_Common::get_rand_str(32,false);
        file_put_contents($keyfile, $acct->key_pem);
        $extras['certPath'] = $certfile;
        $extras['keyPath'] = $keyfile;


        // load()->func('communication');
        $arr = Helper_Common::post_data($url,$pars,"xml",true,$extras); //ihttp_request($url, $xml, $extras);
        @unlink($certfile);
        @unlink($keyfile);

        if ($arr['return_code'] == 'SUCCESS' && $arr['result_code'] == 'SUCCESS') {
            $return['status']=0;
            return $return;
        }

        if ($arr['return_code'] == 'SUCCESS' && $arr['result_code'] == 'FAIL' && $arr['return_msg'] == 'OK') {
            if ($arr['err_code'] == 'NOTENOUGH') {
                $return['msg'] = "账号余额不足";
                return $return;

            }else{
                $return['msg'] = $arr['err_code'];
                return $return;
            }
        }
        else {
            if (empty($arr['err_code_des']) || $arr['return_msg'] == $arr['err_code_des']) {
                $error = $arr['return_msg'];
            }
            else {
                $error = $arr['return_msg'] . ' | ' . $arr['err_code_des'];
            }

            $return['msg'] = $error;
            return $return;
        }
    }

}

